// 创建通用环境配置文件
const HtmlWebpackPlugin = require('html-webpack-plugin')
const paths = require('./paths');
const chalk = require('chalk'); // 该库会生成一些颜色丰富、具有说明性的输出信息，以便在构建过程中更好地调试和输出信息
const ProgressBarPlugin = require('progress-bar-webpack-plugin'); // 编译时进度条


function isEnvProduction(){
    return process.env.NODE_ENV === 'production'
}

module.exports = {
    // 配置入口文件（依赖构建的起点）
    entry : {
        'index': './src/index.js'
    },
    // 配置插件
    plugins: [
        new HtmlWebpackPlugin({
            // title: 'release_v0'  // 简易版生成html自动引入所有的bundle
            template : 'public/index.html', //告诉webpack打包的是哪一个html文件
            filename: 'index.html',  // 打包后的文件名
            chunks : 'index' // 需要将哪个js入口文件导入到这个html中
        }),
        // 进度条(包含内容、进度条、进度百分比、消耗时间，进度条查看编译进度)
        new ProgressBarPlugin({
            format: `  :msg [:bar] ${chalk.green.bold(':percent')} (:elapsed s)`
        })
    ],
    // 配置预处理器
    module: {
        rules: [
            // 【处理图片：小于10KB转Base64编码通过URL访问，大于的将来会自动上传CDN(目前还是在本地images内)】
            {
                test: /\.(png|svg|jpg|jpeg|gif)$/i,
                // exclude:/node_modules/,  //排除在 node_moudules中的图片文件
                include: paths.appSrc, //仅处理src目录下的图片文件
                // type: 'asset/resource', // 允许使用资源文件（字体，图标等）而无需配置额外 loader（ 发送一个单独的文件并导出 URL）
                type:'javascript/auto',  //webpack 5需要加这个配置
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 10240, // 当图片文件小于10KB时,会将图片编码为Base64，否则将图片上传到CDN并返回URL。
                            name: 'images/[name].[hash:8].[ext]', // 输出文件名格式
                            esModule:false //避免插件冲突
                        }
                    }
                    // 如果较大的文件需要上传到CDN，需要在output中配置publicPath来指定CDN的路径
                ]
            },
            {
                test:/\.(html|htm)$/i,
                use:['html-withimg-loader']  //对html中使用img标签的图片进行打包处理
            },
            // 处理字体
            {
                test: /.(woff|woff2|eot|ttf|otf)$/i,
                include: [
                    paths.resolveApp('src'),
                ],
                type: 'asset/resource',
            },
            // 【处理CSS（CSS模块化+自动插入若干style节点）】
            {
                test: /\.css$/,
                include: paths.appSrc,
                use: [
                    'style-loader',    // 此插件会将JS字符串生成为 <style></style>节点插入到 DOM 中（将CSS混合到JS代码中）
                    // 将CSS转化成CommonJS模块(对@import和url()进行处理，让CSS也能模块化开发)
                    'css-loader',
                ]
            },
            // 【处理SASS/SCSS(将sass转换成css)】
            {
                test: /.(scss|sass)$/,
                include: paths.appSrc,
                use: [
                    // 将 JS 字符串生成为 style 节点
                    'style-loader',
                    // 将 CSS 转化成 CommonJS 模块
                    'css-loader',
                    // 将 Sass 编译成 CSS
                    'sass-loader',
                ],
            },
            // 【postCSS是用JavaScript工具和插件转换CSS代码的工具（自动为 CSS 规则添加前缀；将最新的 CSS 语法转换成大多数浏览器都能理解的语法；css-modules 解决全局命名冲突问题）】
            {
                test: /\.module\.(scss|sass)$/,
                include: paths.appSrc,
                use: [
                    // 将 JS 字符串生成为 style 节点
                    'style-loader',
                    // 将 CSS 转化成 CommonJS 模块
                    {
                        loader: 'css-loader',
                        options: {
                            // Enable CSS Modules features
                            modules: true,
                            importLoaders: 2,
                            // 0 => no loaders (default);
                            // 1 => postcss-loader;
                            // 2 => postcss-loader, scss-loader
                        },
                    },
                    // 将 PostCSS 编译成 CSS
                    {
                        loader: 'postcss-loader',
                        options: {
                            postcssOptions: {
                                plugins: [
                                    [
                                        // postcss-preset-env 包含 autoprefixer
                                        'postcss-preset-env',
                                    ],
                                ],
                            },
                        },
                    },
                    {
                        loader: 'thread-loader',  //通过 thread-loader将耗时的 loader 放在一个独立的 worker 池中运行，加快 loader 构建速度
                        options: {
                            workerParallelJobs: 2  //线程池并行任务执行量
                        }
                    },
                    // 将 Sass 编译成 CSS
                    'scss-loader',
                ].filter(Boolean),
            },
            //【 处理 LESS （将less转换成css）】
            {
                test: /\.less$/,
                use: [
                    'style-loader', // 将样式通过 <style> 标签注入到页面
                    'css-loader',   // 处理 CSS 文件中的 import 和 url()
                    'less-loader'   // 将 Less 编译成 CSS
                ],
            },
            //【处理 TypeScript，使用esbuild-loader将ts转换成js】
            {
                test: /\.(js|ts|jsx|tsx)$/,
                include: paths.appSrc,
                use: [
                    {
                        loader: 'esbuild-loader',
                        options: {
                            loader: 'tsx',
                            target: 'es2015',
                        },
                    }
                ]
            },
        ]
    },
    // 配置解析器
    resolve: {
        //别名在JavaScript代码中引用模块时起作用的，而不会直接影响HTML文件中的路径（在HTML文件中，路径引用不会经过Webpack的处理，Webpack只处理JavaScript代码）
        alias: {
            '@': paths.appSrc
        },
        extensions: ['.js', '.jsx', '.json', '.css', '.ts','.tsx'], // 配置引入模块时可以省略的文件扩展名
    },
    // 使用文件缓存(将构建过程的 webpack 模板进行缓存，大幅提升二次构建速度、打包速度，当构建突然中断，二次进行构建时，可以直接从缓存中拉取，可提速 90% 左右)
    cache: {
        type: 'filesystem',
    }
}